from django import http
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
import random
import logging

from apps.verifications.libs.captcha.captcha.captcha import captcha
from . import constants
from meiduo_mall_two.utils.response_code import RETCODE
from apps.verifications.libs.yuntongxun.ccp_sms import sendTemplateSMS
from celery_tasks.sms.tasks import ccp_send_sms_code

# Create your views here.

# 创建一个日志输出器
logger = logging.getLogger("django")


class SMSCodeView(View):
    '''短信验证码'''
    def get(self,request,mobile):

        # 提取并判断发送短信验证码的标记是否存在,如果标记存在,则表示过于频繁
        # 连接redis
        redis_coon = get_redis_connection("verify_code")
        # 获取标记
        send_flag = redis_coon.get("send_flag_%s" % mobile)
        if send_flag:
            return http.JsonResponse({"code":RETCODE.THROTTLINGERR,"errmsg":"发送短信过于频繁"})

        # 接收参数
        image_code_client = request.GET.get("image_code") # str
        uuid = request.GET.get("uuid")

        # 校验参数
        if not all([image_code_client,uuid]):
            return http.HttpResponseForbidden("缺少必传参数")

        # 提取图形验证码
        redis_conn = get_redis_connection("verify_code")
        image_code_server = redis_conn.get("img_%s" % uuid) # bytes
        if not image_code_server:
            return http.JsonResponse({"code":RETCODE.IMAGECODEERR,"errmsg":"图形验证码失效"})

        # 删除图形验证码,为了避免恶意用户测试图形验证码,提取到之后,把验证码从reids中删除
        redis_conn.delete("img_%s" % uuid)

        # 对比图形验证码,如果用户输入的和服务器不一样,就响应错误信息
        # 服务器的时bytes类型所以要解码成字符串才能进行比较
        image_code_server = image_code_server.decode()
        if image_code_client.lower() != image_code_server.lower(): #统一转成小写
            return http.JsonResponse({"code":RETCODE.IMAGECODEERR,"errmsg":"图形验证码有误"})

        # 生成短信验证码 6位数字
        sms_code = "%06d" % random.randint(0,999999)
        # 用日志把短信验证码输入出来
        logger.info(sms_code)

        # 保存短信验证码
        # redis_conn.setex("key",有效期,"value")
        # redis_conn.setex("sms_%s" %mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code)
        # 保存短信验证码的标记
        redis_conn.setex("send_flag_%s" % mobile,constants.SEND_SMS_CODE_INTERVAL,"flag")

        # 创建Redis管道,    利用管道把多个命令打包到一起,就减少了阻塞,两个命令一个请求来完成
        pl = redis_conn.pipeline()
        # 将Redis请求添加到管道,就是一下两行代码
        # 保存短信验证码
        pl.setex("sms_%s" %mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code)
        # 保存短信验证码的标记
        pl.setex("send_flag_%s" % mobile,constants.SEND_SMS_CODE_INTERVAL,"flag")
        # 执行请求
        pl.execute()

        # 发送短信验证码  两个斜线 //  表示整除 5分钟
        # 这是一个耗时操作   sendTemplateSMS(mobile,[sms_code,5],1)
        # sendTemplateSMS(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES // 60],constants.SEND_SMS_TEMPLATE_ID)
        # 异步发送短信
        # ccp_cend_sms_code()  如此调用表示立即执行
        ccp_send_sms_code.delay(mobile,sms_code) # 延迟执行,不要立即执行,可以执行后面的代码

        # 响应结果
        return http.JsonResponse({"code":RETCODE.OK,"errmsg":"发送短信验证码成功"})



class ImageCodeView(View):
    ''' 图形验证码 '''
    def get(self,request,uuid):
        # 接受参数  get后接收参数
        # 验证参数 正则验证了
        # 生成图形验证码
        # text 就是验证码的4个字符,image是图片二进制
        text, image = captcha.generate_captcha()
        # 连接redis数据库
        redis_conn = get_redis_connection("verify_code")
        # 操作redis  setex 设置过期时间
        redis_conn.setex("img_%s" %uuid,constants.IMAGE_CODE_REDIS_EXPIRES,text)
        # 返回响应  (响应图形验证码iamge
        return http.HttpResponse(image,content_type="image/jpg")